import React, { useEffect, useMemo, useState } from "react";
//  hooks

// React
// 1. useEffect
// 2. useState
// 3. useContext
// 4. useCallback
// 5. useId
// 6.

// react-router-dom
// useParams
const Index: React.FC = () => {
  // hooks 规则
  // 1. 必须在函数组件顶层使用
  // 2. 不可以在循环或者条件语句中使用
  //    原因是hooks 是一个链表结构， 会破坏结构， 导致数据更新不正确

  // 1. 用来 声明 状态变量
  const [count, setCount] = useState(1);
  // 1-1 set 函数 仅更新 下一次 渲染的状态变量。如果在调用 set 函数后读取状态变量，则 仍会得到在调用之前显示在屏幕上的旧值。

  // 1-2 如果你提供的新值与当前 state 相同（由 Object.is 比较确定），React 将 跳过重新渲染该组件及其子组件。这是一种优化。虽然在某些情况下 React 仍然需要在跳过子组件之前调用你的组件，但这不应影响你的代码。

  // 1-3 React 会 批量处理状态更新。它会在所有 事件处理函数运行 并调用其 set 函数后更新屏幕。这可以防止在单个事件期间多次重新渲染。在某些罕见情况下，你需要强制 React 更早地更新屏幕，例如访问 DOM，你可以使用 flushSync。

  const handleAdd = () => {
    setCount((count) => count + 1); // 2
  };
  // 2. useEffect  副作用函数
  // 2-1
  // useEffect(() => {
  //   // 1. 时机： 当组件被添加到 DOM 的时候，React 将运行 setup 函数    componentDidMount()
  //   const btn = document.querySelector("button");
  //   console.log(btn);
  //   // 2. 在每次依赖项变更重新渲染后，React 将首先使用旧值运行 cleanup 函数（如果你提供了该函数），然后使用新值运行 setup 函数   componentDidUpdate()

  //   // 3. 在组件从 DOM 中移除后，React 将最后一次运行 cleanup 函数
  //   // 清理函数  componentDidUpdate()
  //   return () => {
  //     console.log("cleanup 函数 执行");
  //   };
  // }, [count]);
  // 它在每次重新渲染的时候能够缓存计算的结果
  
  const result = useMemo(() => {
    console.log("fn 执行了");
    let s = 0;
    for (let i = 0; i <= 1000000; i++) {
      s += i;
    }
    return s;
  }, []);

  return (
    <div>
      <h1>count: {count}</h1>
      <button onClick={() => handleAdd()}>值 +1</button>

      <h2>{result}</h2>
    </div>
  );
};

export default Index;
